package sdk.pay.model;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Base64;
import org.json.JSONException;
import org.json.JSONObject;
import sdk.pay.basepay.UnifiedPay;
import sdk.pay.utils.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;

/**
 * Created by Administrator on 2017/5/22.
 */

public class FlexiblePay extends UnifiedPay {
    private static final String QR_CODE_MSG = "create qrCode failed!";
    private static final String SUFFIX_SHARE = "_share.jpg";
    private static final String SUFFIX_SCAN = "_scan.jpg";
    private static final String QR_CODE_FOLDER_NAME = "qrCode";

    public FlexiblePay(String content, Context context) {
        super(content, context);
    }

    @Override
    public void pay(CallBack callBack) {
        mCallBack = callBack;
        String result = decryptContent(getContent());
        if (null != result) {
            JSONObject object;
            try {
                object = new JSONObject(result);
                String paramList = object.getString("paramList");
                JSONObject objectParam = new JSONObject(paramList);
                String url = objectParam.getString("url");
                String type = objectParam.getString("type");
                PayLogUtil.logFifth("type = " + type + " url = " + url);
                if (!TextUtils.isEmpty(type) && !TextUtils.isEmpty(url)) {
                    switch (type) {
                        case "3":
                            qrCodePay(url, "wx");
                            break;
                        case "4":
                            sendBitmapToFriend(url);
                            break;
                        // TODO: 2018/11/24 ali scan qr pay
                        case "13":
                            qrCodePay(url, "ali");
                            break;
                        default:
                            sendUrlToFriend(url);
                            break;
                    }
                } else {
                    PayLogUtil.logBase("pay type or url is null");
                }
            } catch (JSONException e) {
                PayLogUtil.logFourth("pay json exception reason " + e.getMessage());
                e.printStackTrace();
                PayExceptionUtil.getInstance().saveExceptionFile(
                        "pay json exception reason " + e.getMessage());
            }
        } else {
            PayLogUtil.logBase("pay result is null");
        }
    }

    private String decryptContent(String content) {
        String result = null;
        if (!TextUtils.isEmpty(content)) {
            content = content.replace("-", "+")
                    .replace("_", "/")
                    .replace("~", "=");
            byte[] decryptFrom = Base64.decode(content, Base64.DEFAULT);
            byte[] decryptResult = PayAESUtil.decrypt(decryptFrom, "", "");
            if (null == decryptResult) {
                PayLogUtil.logBase("getPayTypes decryptResult exception");
            }
            result = new String(decryptResult != null ? decryptResult : new byte[0]);
        }
        PayLogUtil.logBase(result);
        return result;
    }

    /**
     * send url to weixin
     *
     * @param url pay address
     */
    private void sendUrlToFriend(String url) {
        PayLogUtil.logBase("sendUrlToFriend url = " + url);
        url = URLDecoder.decode(url);
        Intent intent = new Intent();
        ComponentName comp = new ComponentName("com.tencent.mm",
                "com.tencent.mm.ui.tools.ShareImgUI");
        intent.setComponent(comp);
        intent.setAction("android.intent.action.SEND");
        intent.setType("text/*");
        intent.putExtra(Intent.EXTRA_TEXT, url);
        startWeiXin(intent);
        PayLogUtil.logFifth("sendUrlToFriend end");
    }

    private void sendBitmapToFriend(String url) {
        PayLogUtil.logBase("sendBitmapToFriend url = " + url);
        Bitmap qrCode = PayQRCodeUtil.createQRCodeBitmap(url, 200, 200);
        if (null != qrCode) {
            File file = saveAndGetFile(qrCode);
            if (null != file) {
                Intent intent = new Intent();
                ComponentName comp = new ComponentName("com.tencent.mm",
                        "com.tencent.mm.ui.tools.ShareImgUI");
                intent.setComponent(comp);
                intent.setAction("android.intent.action.SEND");
                intent.setType("image/*");
                Uri uri;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    uri = FileProvider.getUriForFile(mContext, getFileProvider(), file);
                } else {
                    uri = Uri.fromFile(file);
                }
                intent.putExtra(Intent.EXTRA_STREAM, uri);
                startWeiXin(intent);
            } else {
                PayLogUtil.logBase("sendBitmapToFriend file not exsit");
            }
        } else {
            PayLogUtil.logBase("sendBitmapToFriend bitmap not exsit");
        }
    }

    private String getFileProvider() {
        String auth = null;
        try {
            ProviderInfo[] providers = mContext.getPackageManager().getPackageInfo(
                    mContext.getPackageName(), PackageManager.GET_PROVIDERS).providers;
            for (ProviderInfo info : providers) {
                if (info.name.equals("android.support.v4.content.FileProvider")) {
                    auth = info.authority;
                    PayLogUtil.logBase("getFileProvider auth = " + auth);
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("getPayTypes onResponse " +
                    "PackageManager.NameNotFoundException = " + e.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile("getPayTypes " +
                    "onResponse PackageManager.NameNotFoundException = " + e.getMessage());
        }
        return auth;
    }

    private void startWeiXin(Intent intent) {
        try {
            mContext.startActivity(intent);
        } catch (Exception e) {
            PayLogUtil.logFourth("startWeiXin reason = " + e.getMessage());
            e.printStackTrace();
            PayToastUtil.showMessage(mContext, "WeiXin can't be found!");
            PayExceptionUtil.getInstance().saveExceptionFile("startWeiXin " +
                    "Exception e = " + e.getMessage());
        } finally {
            prepareLeave();
        }
    }

    private void startAli(Intent intent) {
        try {
            mContext.startActivity(intent);
        } catch (Exception e) {
            PayLogUtil.logFourth("startAli reason = " + e.getMessage());
            e.printStackTrace();
            PayToastUtil.showMessage(mContext, "AliPay can't be found!");
            PayExceptionUtil.getInstance().saveExceptionFile("startAli " +
                    "Exception e = " + e.toString());
        } finally {
            prepareLeave();
        }
    }

    /**
     * generate qrCode,and call weChat scanner
     *
     * @param qrCodeAddress String
     * @param type          ali or wx
     */
    private void qrCodePay(String qrCodeAddress, String type) {
        Bitmap qrCode = PayQRCodeUtil.createQRCodeBitmap(qrCodeAddress, 200, 200);
        if (null == qrCode) {
            PayLogUtil.logBase(QR_CODE_MSG);
            PayExceptionUtil.getInstance().saveFile(QR_CODE_MSG);
            return;
        }
        saveImageToGallery(qrCode);
        switch (type) {
            case "ali":
                startAliScanner();
                break;
            case "wx":
                startWXScanner();
                break;
        }
    }

    /**
     * call weChat scanner
     */
    private void startWXScanner() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MAIN);
        ComponentName com = new ComponentName("com.tencent.mm",
                "com.tencent.mm.ui.LauncherUI");
        intent.setComponent(com);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.putExtra("LauncherUI.From.Scaner.Shortcut", true);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startWeiXin(intent);
    }

    /**
     * call ali scanner
     */
    private void startAliScanner() {
        Uri uri = Uri.parse("alipays://platformapi/startapp?appId=10000007");
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startAli(intent);
    }

    /**
     * save bitmap to file
     *
     * @param bitmap Bitmap
     * @return File
     */
    private File saveAndGetFile(Bitmap bitmap) {
        File appDir = new File(Environment.getExternalStorageDirectory(), QR_CODE_FOLDER_NAME);
        PayFileUtil.deleteFile(mContext, appDir);
        PayFileUtil.createFolder(appDir);
        String date = PayDateFormatUtil.getDate();
        String fileName = date + SUFFIX_SHARE;
        File file = new File(appDir, fileName);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("saveAndGetFile FileNotFoundException = " + e.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile("saveAndGetFile " +
                    "FileNotFoundException = " + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("saveAndGetFile IOException = " + e.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile("saveAndGetFile " +
                    "IOException = " + e.getMessage());
        } finally {
            PayAutoCloseUtil.quietClose(fos);
        }
        return file;
    }

    /**
     * save bitmap on sdcard
     *
     * @param bmp Bitmap
     */
    private void saveImageToGallery(Bitmap bmp) {
        File appDir = new File(Environment.getExternalStorageDirectory(), QR_CODE_FOLDER_NAME);
        PayFileUtil.deleteFile(mContext, appDir);
        PayFileUtil.createFolder(appDir);
        String date = PayDateFormatUtil.getDate();
        PayLogUtil.logBase("date = " + date);
        String fileName = date + SUFFIX_SCAN;
        File file = new File(appDir, fileName);
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 90, fos);
            fos.flush();
            MediaScannerConnection.scanFile(mContext, new String[]{
                            Environment.getExternalStorageDirectory() + File.separator +
                                    QR_CODE_FOLDER_NAME + File.separator + fileName},
                    null, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("saveImageToGallery FileNotFoundException = " + e.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile("saveImageToGallery " +
                    "FileNotFoundException = " + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("saveImageToGallery IOException = " + e.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile("saveImageToGallery " +
                    "IOException = " + e.getMessage());
        } finally {
            PayAutoCloseUtil.quietClose(fos);
        }
    }
}